package cn.school.notice.service.impl;

import cn.school.async.AsyncConfig;
import cn.school.classManage.dao.SchoolClassDao;
import cn.school.classManage.vo.SchoolClassVO;
import cn.school.common.utils.SysUserUtils;
import cn.school.notice.dao.SchoolNoticeDao;
import cn.school.notice.dao.SchoolNoticeUserDao;
import cn.school.notice.entity.SchoolNotice;
import cn.school.notice.entity.SchoolNoticeUser;
import cn.school.notice.service.SchoolNoticeService;
import cn.school.student.dao.StudentInfoDao;
import cn.school.student.entity.StudentInfo;
import cn.school.sys.dao.SysUserDao;
import cn.school.sys.entity.SysUser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
public class SchoolNoticeServiceImpl extends ServiceImpl<SchoolNoticeDao, SchoolNotice> implements SchoolNoticeService {

    @Autowired
    private SchoolNoticeDao schoolNoticeDao;

    @Resource
    private SchoolClassDao schoolClassDao;
    @Resource
    private SchoolNoticeUserDao schoolNoticeUserDao;
    @Resource
    private StudentInfoDao studentInfoDao;
    @Resource
    private SysUserDao sysUserDao;
    @Resource
    private AsyncConfig asyncConfig;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(SchoolNotice schoolNotice) {
        String userName = SysUserUtils.getSysUser().getUsername();
        schoolNotice.setCreateBy(userName);
        schoolNotice.setCreateTime(new Date());
        if ("1".equals(schoolNotice.getReleaseScopeNotice())) {
            schoolNotice.setClassId(org.apache.commons.lang.StringUtils.join(schoolNotice.getClassIds(), ","));
        }
        if ("2".equals(schoolNotice.getReleaseScopeNotice())) {
            schoolNotice.setGradeId(schoolNotice.getGrade());
        }
        int num = schoolNoticeDao.insert(schoolNotice);
        //发送通知
        if ("1".equals(schoolNotice.getIsSend())) {
            this.sendNoticeToUser(schoolNotice);
        }


        return Integer.valueOf(schoolNotice.getId()+"");
    }

    @Override
    public void sendNoticeToUser(SchoolNotice schoolNotice) {
        List<SchoolClassVO> classList = null;
        SchoolNoticeUser noticeUser = null;
        List<SysUser> userList = new ArrayList<>();
        if(!StringUtils.isEmpty(schoolNotice.getNoticeDepts())){
            userList = getDeptUsers(schoolNotice);
        }
        if ("1".equals(schoolNotice.getReleaseScopeNotice())) {//班级
            //查询班级的班主任信息
            classList = schoolNoticeDao.findSchoolClassByClassId(schoolNotice.getClassIds());
        }
        if ("2".equals(schoolNotice.getReleaseScopeNotice())) {//年级
            classList = schoolNoticeDao.findSchoolClassByGrade(schoolNotice.getGrade(), SysUserUtils.getSysUser().getTenantId());
        }
        if ("3".equals(schoolNotice.getReleaseScopeNotice())) {//全校
            classList = schoolNoticeDao.findSchoolClassAll(SysUserUtils.getSysUser().getTenantId());
        }
        List<SysUser> userNameList = removeDoubleList(userList,classList);
        //发送通知给老师
        asyncConfig.sendSchoolNoticeToUser(userNameList,schoolNotice.getId(),schoolNotice);
        if ("1".equals(schoolNotice.getIsNoticeStudent())) {//通知学生
            LambdaQueryWrapper<StudentInfo> wrapper = null;
            for (SchoolClassVO classVO : classList) {
                wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(StudentInfo::getClassId, classVO.getId());
                wrapper.eq(StudentInfo::getStatus, 1);
                List<StudentInfo> studentList = studentInfoDao.selectList(wrapper);
                asyncConfig.sendSchoolNoticeToStudent(studentList,schoolNotice,classVO.getId());
            }
        }
        SchoolNotice snVO = new SchoolNotice();
        snVO.setId(schoolNotice.getId());
        snVO.setIsSend("1");
        schoolNoticeDao.updateById(snVO);
    }

    private List<SysUser> removeDoubleList(List<SysUser> deptUserList, List<SchoolClassVO> classList){
        List<SysUser> listNew=new ArrayList<>();
        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        if(deptUserList.size()>0){
            SchoolClassVO vo = null;
            for(SchoolClassVO classVO:classList){
                userWrapper.eq(SysUser::getUsername,classVO.getClassTeacherId());
                userWrapper.eq(SysUser::getTenantId, SysUserUtils.getSysUser().getTenantId());
                SysUser sysUser = sysUserDao.selectOne(userWrapper);
                deptUserList.add(sysUser);
            }
            //用户去重
            Set set=new HashSet();
            for(SysUser user : deptUserList){
                if(set.add(user.getUsername())){
                    listNew.add(user);

                }
            }

        }else{
            deptUserList = new ArrayList<>();
            //用户去重
            Set set=new HashSet();

            for(SchoolClassVO classVO:classList){

                if(set.add(classVO.getClassTeacherId())){
                    userWrapper.eq(SysUser::getUsername,classVO.getClassTeacherId());
                    userWrapper.eq(SysUser::getTenantId, SysUserUtils.getSysUser().getTenantId());
                    SysUser sysUser = sysUserDao.selectOne(userWrapper);
                    listNew.add(sysUser);
                }
            }
        }
        return listNew;
    }

    private List<SysUser>  getDeptUsers(SchoolNotice schoolNotice) {
        List deptList =  JSON.parseObject(schoolNotice.getNoticeDepts(),List.class);
        List<String> depts = new ArrayList<>();
        Map<String,String> map = new HashMap<>();
        if(deptList==null){
            return new ArrayList<>();
        }
        for(int i=0;i<deptList.size();i++){
            JSONArray jsonArray = (JSONArray)deptList.get(i);
            for (Object deptId :jsonArray){
                map.put(String.valueOf(deptId),String.valueOf(deptId));
            }
        }
        for (String key : map.keySet()) {
            depts.add(key);
        }

        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.in(SysUser::getDeptId,depts);

        return sysUserDao.selectList(userWrapper);
    }

    @Override
    public int deleteNotice(SchoolNotice schoolNotice) {
        int i = schoolNoticeDao.deleteById(schoolNotice.getId());
        return i;
    }

    @Override
    public int update(SchoolNotice schoolNotice) {
        String userName = SysUserUtils.getSysUser().getUsername();
        schoolNotice.setModifyBy(userName);
        schoolNotice.setModifyTime(new Date());
        if ("1".equals(schoolNotice.getReleaseScopeNotice())) {
            schoolNotice.setClassId(org.apache.commons.lang.StringUtils.join(schoolNotice.getClassIds(), ","));
        }
        if ("2".equals(schoolNotice.getReleaseScopeNotice())) {
            schoolNotice.setGradeId(schoolNotice.getGrade());
        }
        return schoolNoticeDao.updateById(schoolNotice);
    }

    @Override
    public int batchUpdateNotice(List<SchoolNotice> list) {
        int num = 0;
        for (SchoolNotice sn : list) {
            schoolNoticeDao.updateById(sn);
            num++;
        }
        return num;
    }

    @Override
    public SchoolNotice selectById(Long id) {
        SchoolNotice sn = schoolNoticeDao.selectById(id);
        if ("1".equals(sn.getReleaseScopeNotice())) {
            List<String> list = Arrays.asList(sn.getClassId().split(","));
            if (list != null && list.size() > 0) {
                sn.setClassIds(list);
            }

        }
        if ("2".equals(sn.getReleaseScopeNotice())) {
            sn.setGrade(sn.getGradeId());
        }
        return sn;
    }

    @Override
    public IPage<SchoolNotice> findNoticePageList(SchoolNotice schoolNotice) {


        LambdaQueryWrapper<SchoolNotice> wrapper = new LambdaQueryWrapper<>();
        //查询指定字段
        wrapper.select(SchoolNotice::getId, SchoolNotice::getTitle, SchoolNotice::getNoticeType, SchoolNotice::getIsNoticeStudent, SchoolNotice::getGradeId,
                SchoolNotice::getReleaseScopeNotice, SchoolNotice::getIsSend, SchoolNotice::getCreateTime, SchoolNotice::getStatus, SchoolNotice::getClassId,
                SchoolNotice::getNoticeDepts);
        wrapper.eq(!StringUtils.isEmpty(schoolNotice.getIsNoticeStudent()), SchoolNotice::getIsNoticeStudent, schoolNotice.getIsNoticeStudent());
        wrapper.eq(!StringUtils.isEmpty(schoolNotice.getStatus()), SchoolNotice::getStatus, schoolNotice.getStatus());
        wrapper.eq(!StringUtils.isEmpty(schoolNotice.getIsSend()), SchoolNotice::getIsSend, schoolNotice.getIsSend());
        wrapper.eq(!StringUtils.isEmpty(schoolNotice.getReleaseScopeNotice()), SchoolNotice::getReleaseScopeNotice, schoolNotice.getReleaseScopeNotice());
        wrapper.eq(!StringUtils.isEmpty(schoolNotice.getNoticeType()), SchoolNotice::getNoticeType, schoolNotice.getNoticeType());
        wrapper.like(!StringUtils.isEmpty(schoolNotice.getTitle()), SchoolNotice::getTitle, schoolNotice.getTitle());
        //租户
        wrapper.eq(SchoolNotice::getTenantId,SysUserUtils.getSysUser().getTenantId());
        wrapper.orderByDesc(SchoolNotice::getId);

        IPage<SchoolNotice> page = page(new Page<>(schoolNotice.getPageNum(), schoolNotice.getPageSize()), wrapper);
        return page;
    }


    @Override
    public IPage<SchoolNotice> findSchoolNoticeByUserPageList(SchoolNotice vo) {
        String user = SysUserUtils.getSysUser().getUsername();
        if(StringUtils.isEmpty(user)){
            user = SysUserUtils.getStudentUser().getStudentId();
        }
        if(StringUtils.isEmpty(user)){
            user = SysUserUtils.getParentUser().getStudentId();
        }
        vo.setRecipient(user);
        vo.setTenantId(SysUserUtils.getSysUser().getTenantId());
        int count = schoolNoticeDao.findSchoolNoticeByUserCount(vo);
        int startNum = (vo.getPageNum() - 1) * vo.getPageSize();
        vo.setPageNum(startNum);
        List<SchoolNotice> commentList = schoolNoticeDao.findSchoolNoticeByUserPageList(vo);
        IPage<SchoolNotice> page = new Page<>();
        page.setTotal(count);
        page.setRecords(commentList);
        return page;
    }

    @Override
    public int readyNotice(SchoolNotice schoolNotice) {
        LambdaQueryWrapper<SchoolNoticeUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SchoolNoticeUser::getRecipient, SysUserUtils.getSysUser().getUsername());
        wrapper.eq(SchoolNoticeUser::getNoticeId, schoolNotice.getId());
        SchoolNoticeUser notice = new SchoolNoticeUser();
        notice.setStatus("1");
        return schoolNoticeUserDao.update(notice, wrapper);
    }
}
